package cn.edu.cqut.mdm.initialize;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import cn.edu.cqut.mdm.container.LocalDefinedModuleContainer;
import cn.edu.cqut.mdm.container.PublisherDispatcherContainer;
import cn.edu.cqut.mdm.core.GlobalConfigManager;
import cn.edu.cqut.mdm.core.exception.ModuleDefinationException;
import cn.edu.cqut.mdm.core.module.Module;
import cn.edu.cqut.mdm.core.module.ModuleEntity;
import cn.edu.cqut.mdm.core.module.PublishStatus;
import cn.edu.cqut.mdm.core.publish.Publish;
import cn.edu.cqut.mdm.core.publisherdispatcher.PublisherDispatcher;
import cn.edu.cqut.mdm.initialize.interceptor.InitializeInterceptor;


public class ModuleInitializer {
	public void initialize(String... base) {
		List<InitializeInterceptor> interceptors = getInitializeInterceptors();
		Set<Class<?>> classes = new PackageScanner(base).doScan();
		for(Class<?> clazz : classes) {
			if(clazz.isAnnotationPresent(Module.class)){
				Module moduleAnnotation = clazz.getAnnotation(Module.class);
				if(moduleAnnotation.uid() == null){
					throw new ModuleDefinationException("模块uid不能为空");
				}
				
				ModuleEntity moduleEntity = new ModuleEntity(moduleAnnotation.uid(), moduleAnnotation.name(), clazz, Arrays.asList(clazz.getDeclaredMethods()));
				
				for(InitializeInterceptor interceptor : interceptors) {
					moduleEntity = interceptor.beforeModuleInitialize(moduleEntity);
				}
				
				LocalDefinedModuleContainer.getInstance().addModule(moduleEntity);
				for(PublisherDispatcher publisherDispatcher : PublisherDispatcherContainer.getInstance().getAllPublisherDispatcherMap().values()) {
					moduleEntity.addPublishStatus(new PublishStatus(publisherDispatcher, moduleEntity));
				}
				// 发布
				if(moduleEntity.getModuleClazz().isAnnotationPresent(Publish.class)) {
					Publish publish = moduleEntity.getModuleClazz().getAnnotation(Publish.class);
					String[] publisherNames = publish.value();
					for(String publisherName : publisherNames) {
						PublisherDispatcher publisherDispatcher = PublisherDispatcherContainer.getInstance().getPublisherDispatcher(publisherName);
						publisherDispatcher.getPublisher().publish(moduleEntity);
					}
				}
				
				for(InitializeInterceptor interceptor : interceptors) {
					moduleEntity = interceptor.afterModuleInitialize(moduleEntity);
				}
			}
		}
	}
	private List<InitializeInterceptor> getInitializeInterceptors(){
		String interceptorClassNames = GlobalConfigManager.getInstance().get(GlobalConfigManager.MODULE_INITIALIZE_INTERCEPTORS);
		if(interceptorClassNames == null){
			return new ArrayList<InitializeInterceptor>();
		}
		List<InitializeInterceptor> result = new ArrayList<InitializeInterceptor>();
		for(String interceptorClassName : interceptorClassNames.split(",")){
			if(interceptorClassName.trim().equals("")){
				continue;
			}
			try {
				result.add((InitializeInterceptor) Class.forName(interceptorClassName).newInstance());
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return result;
	}
}
